#include "Vec2.h"
#include "Error.h"
#include <cmath>

namespace Engine
{
	Vec2::Vec2():x(0.0f), y(0.0f){}

	Vec2::Vec2(float _x, float _y):x(_x), y(_y){}

	Vec2& Vec2::operator+=(const Vec2& rhs)
	{
		x += rhs.x;
		y += rhs.y;
	
		return (*this);
	}
	
	Vec2& Vec2::operator+=(float a)
	{
		x += a;
		y += a;
	
		return (*this);
	}
	
	Vec2 Vec2::operator+(const Vec2& rhs) const
	{
		Vec2 temp = (*this);
		temp += rhs;
	
		return temp;
	}
	
	Vec2 Vec2::operator+(float a) const
	{
		Vec2 temp = (*this);
		temp += a;
	
		return temp;
	}
	
	Vec2& Vec2::operator-=(const Vec2& rhs)
	{
		x -= rhs.x;
		y -= rhs.y;
	
		return (*this);
	}
	
	Vec2 Vec2::operator-(const Vec2& rhs) const
	{
		Vec2 temp = (*this);
		temp -= rhs;
	
		return temp;
	}
	
	Vec2& Vec2::operator-=(float a)
	{
		x -= a;
		y -= a;
	
		return (*this);
	}
	
	Vec2 Vec2::operator-(float a) const
	{
		Vec2 temp = (*this);
		temp -= a;
	
		return temp;
	}

	Vec2 Vec2::operator-() const {return Vec2(-x, -y);}
	
	Vec2& Vec2::operator*=(float a)
	{
		x *= a;
		y *= a;
	
		return (*this);
	}

	Vec2 Vec2::operator*(float a) const {return Vec2(x * a, y * a);}
	
	Vec2& Vec2::operator*=(Vec2& rhs)
	{
		x *= rhs.x;
		y *= rhs.y;
	
		return (*this);
	}
	
	Vec2 Vec2::operator*(Vec2& rhs) const
	{
		Vec2 temp = (*this);
		temp *= rhs;
	
		return temp;
	}

	bool Vec2::IsEqualTo(Vec2& param)
	{
		Vec2 temp = (*this);

		return ((temp.x == param.x) && (temp.y == param.y));
	}

	float& Vec2::operator[](unsigned int index)
	{
		switch(index)
		{
			case 0:
				return x;

			case 1:
				return y;

				//to stop compiler warnings, this will never get executed
			default:
				Error("Attempting to access a non existing member of Vec3");
				return y;
		}
	}

	const float* Vec2::ToArray(){return &x;}

	float Vec2::Length() const {return std::sqrtf(x*x + y*y);}
	
	void Vec2::Normalize()
	{
		float oneOverLength = 1.0f / std::sqrtf(x*x + y*y);
		(*this) *= oneOverLength;
	}

	float Vec2::SquaredLength() const {return (x*x + y*y);}
	
	float DotProduct(const Vec2& a, const Vec2& b)
	{
		return ((a.x * b.x) + (a.y * b.y));
	}
}
